package com.clear.honghefinance.biz.modules.system.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.clear.honghefinance.biz.modules.system.member.domain.entity.MemberBindPhone;
import com.clear.honghefinance.biz.modules.system.member.domain.vo.AdminDTO;
import com.clear.honghefinance.biz.modules.system.member.domain.dto.UpdatePasswordDTO;
import com.clear.honghefinance.biz.modules.system.member.domain.dto.UpdatePhoneDTO;
import com.clear.honghefinance.biz.modules.system.member.mapper.MemberBindPhoneMapper;
import com.clear.honghefinance.biz.modules.system.member.service.MemberBindPhoneService;
import com.clear.honghefinance.common.exception.BizException;
import com.clear.honghefinance.common.exception.ParameterException;
import com.clear.honghefinance.common.service.TokenService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;

@Service
@Slf4j
public class MemberBindPhoneServiceImpl extends ServiceImpl<MemberBindPhoneMapper, MemberBindPhone> implements MemberBindPhoneService {

    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private TokenService<AdminDTO> tokenService;

    /**
     * 根据手机号获取用户信息
     *
     * @param phone 手机号
     * @return 用户信息
     */
    @Override
    public MemberBindPhone getMemberByPhone(String phone) {
        // todo
        LambdaQueryWrapper<MemberBindPhone> queryWrapper = Wrappers.<MemberBindPhone>lambdaQuery()
                .eq(MemberBindPhone::getPhone, phone);

        return this.getOne(queryWrapper);
    }

    /**
     * 手机号注册
     *
     * @param phone    手机号
     * @param password 密码
     * @param memberId 用户id、会员id
     * @return
     */
    @Override
    public boolean register(String phone, String password, long memberId) {
        MemberBindPhone memberBindPhone = new MemberBindPhone();
        memberBindPhone.setMemberId(memberId);
        memberBindPhone.setPhone(phone);
        memberBindPhone.setPassword(passwordEncoder.encode(password));
        memberBindPhone.initDefault();

        return this.save(memberBindPhone);
    }

    /**
     * 修改密码
     *
     * @param dto
     * @return
     */
    @Override
    public boolean updatePassword(UpdatePasswordDTO dto) {
        if (log.isInfoEnabled()) {
            log.info("修改邮箱和姓名中，入参：{}", JSON.toJSONString(dto));
        }
        try {
            // 校验两次密码是否一致
            if (!Objects.equals(dto.getPassword(), dto.getConfirmPassword())) {
                throw new ParameterException("两次输入的密码不一致");
            }
            // 根据token获取用户信息
            MemberBindPhone memberBindPhone = getById(tokenService.getThreadLocalUserId());
            if (memberBindPhone == null) {
                throw new BizException("账号信息不存在");
            }
            if (memberBindPhone.getDisable()) {
                throw new BizException("账号已被禁用，无法修改密码");
            }
            // 校验旧密码
            if (!passwordEncoder.matches(dto.getOldPassword(), memberBindPhone.getPassword())) {
                throw new BizException("旧密码不正确");
            }
            String newPassword = passwordEncoder.encode(dto.getPassword());
            LambdaUpdateWrapper<MemberBindPhone> lambdaUpdateWrapper = Wrappers.<MemberBindPhone>lambdaUpdate()
                    .eq(MemberBindPhone::getMemberId, memberBindPhone.getMemberId())
                    .set(MemberBindPhone::getPassword, newPassword)
                    .set(MemberBindPhone::getUpdateTime, System.currentTimeMillis());

            if (this.update(lambdaUpdateWrapper)) {
                // 清空token
                tokenService.clearToken();
                return true;
            } else {
                throw new BizException("密码修改失败");
            }
        } catch (Exception e) {
            log.error("密码修改异常 {}", e.getMessage(), e);
            throw new BizException("密码修改失败");
        }
    }

    /**
     * 修改手机号
     *
     * @param dto
     * @return
     */
    @Override
    public boolean updatePhone(UpdatePhoneDTO dto) {
        LambdaUpdateWrapper<MemberBindPhone> lambdaUpdateWrapper = Wrappers.<MemberBindPhone>lambdaUpdate()
                .eq(MemberBindPhone::getMemberId, tokenService.getThreadLocalUserId())
                .eq(MemberBindPhone::getDisable, false)
                .set(MemberBindPhone::getPhone, dto.getPhone())
                .set(MemberBindPhone::getUpdateTime, System.currentTimeMillis());
        return this.update(lambdaUpdateWrapper);
    }
}
